package sd.qd.xiaoming.coffeedesk.dao;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import sd.qd.xiaoming.coffeedesk.entity.BaseEntity;

public class BaseDAO<T extends BaseEntity> {

	private Class<T> entityClass;

	@PersistenceContext
	protected EntityManager entityManager;

	protected BaseDAO(final Class<T> clas) {
		this.entityClass = clas;
	}

	public void delete(final T... entitys) {
		for (int i = 0; i < entitys.length; i++) {
			delete(entitys[i]);
		}
	}

	public void delete(final T entity) {
        this.entityManager.remove(findById(entity.getId()));
	}

	public List<T> findAll() {
		CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
		CriteriaQuery<T> queryCra = builder.createQuery(this.entityClass);
		queryCra.select(queryCra.from(this.entityClass));
		return queryList(queryCra);
	}

	public T findById(final Long id) {
		CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
		CriteriaQuery<T> queryCra = builder.createQuery(this.entityClass);
		Root<T> from = queryCra.from(this.entityClass);
		queryCra.select(from);
		queryCra.where(builder.equal(from.get("id"), id));
		return queryEntity(queryCra);
	}

	public T[] merge(final T... entitys) {
		T[] result = Arrays.copyOf(entitys, entitys.length);
		for (int i = 0; i < entitys.length; i++) {
			result[i] = merge(entitys[i]);
		}
		return result;
	}

	public T merge(final T entity) {
		if (null == entity.getId()) {
            this.entityManager.persist(entity);
            return entity;
		}
        return this.entityManager.merge(entity);
	}

	/**
	 * 查询列表
	 * 
	 * @param criteria
	 *            条件
	 * @return 结果
	 */
	private T queryEntity(final CriteriaQuery<T> criteria) {
		try {
			TypedQuery<T> query = this.entityManager.createQuery(criteria);
			T result = query.getSingleResult();
			return result;
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 查询列表
	 * 
	 * @param criteria
	 *            条件
	 * @return 结果列表
	 */
	private List<T> queryList(final CriteriaQuery<T> criteria) {
		try {
			TypedQuery<T> query = this.entityManager.createQuery(criteria);
			List<T> result = query.getResultList();
			return result;
		} catch (Exception e) {
			return new ArrayList<T>();
		}
	}

	public T[] save(final T... entitys) {
		T[] result = Arrays.copyOf(entitys, entitys.length);
		for (int i = 0; i < entitys.length; i++) {
			result[i] = save(entitys[i]);
		}
		return result;
	}


	public T save(final T entity) {
		this.entityManager.persist(entity);
		return entity;
	}


	public T[] update(final T... entitys) {
		T[] result = Arrays.copyOf(entitys, entitys.length);
		for (int i = 0; i < entitys.length; i++) {
			result[i] = update(entitys[i]);
		}
		return result;
	}

	public T update(final T entity) {
		return this.entityManager.merge(entity);
	}

}
